﻿#region Copyright(C) 2006-2009 FI Ltd. All rights reserved.

// ==================================================================================================
// Copyright(C) 2006-2009 FI Ltd. All rights reserved.
//
// SYSTEM NAME	:   FI.Net Application Framework
// COMPONENT ID :   FI.Logging
// COMPONENT DESC:  Provides logging functionality.
//
// CREATED DATE/BY: 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY:	DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// 5 Jan 2009/Li Hu Sheng                  Rename ServiceException to ServiceExceptionDetail
// ==================================================================================================
#endregion

using FI.Core;
using FI.Core.IoC;
using FI.Core.Localization.Configuration;
using FI.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace FI.Core.Instrumentation
{
    /// <summary>
    /// The context of activty instrumentation.
    /// </summary>
    [Serializable]
    public class ActivityContext
    {
        #region Private Fields
        [ThreadStatic]
        private static ActivityContext current;
        #endregion

        #region Constants
        /// <summary>
        /// The name of ActivityContext header in message.
        /// </summary>
        public const string MessagePropertyName = "ActivityContextMessagePropertyName";

        /// <summary>
        /// The name of ActivityContext MessageProperty name.
        /// </summary>
        public const string MessageHeaderName = "ActivityContextMessageHeaderName";
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets the activity ID.
        /// </summary>
        public Guid ActivityId { get; private set; }

        /// <summary>
        /// Gets the module ID.
        /// </summary>
        public string ModuleId { get; private set; }

        /// <summary>
        /// Gets the name of the activity.
        /// </summary>
        /// <value>
        /// The name of the activity.
        /// </value>
        public string ActivityName { get; private set; }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>
        /// The description.
        /// </value>
        public string Description { get; set; }

        /// <summary>
        /// Gets the start time.
        /// </summary>
        public DateTime StartTime { get; private set; }

        /// <summary>
        /// Gets or sets the call stack level.
        /// </summary>
        /// <value>
        /// The call stack level.
        /// </value>
        public int CallStackLevel { get; set; }

        /// <summary>
        /// Gets the exteneded properties.
        /// </summary>
        public IDictionary<string, object> ExtendedProperties { get; private set; }


        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="ActivityContext"/> class.
        /// </summary>
        /// <param name="moduleId">Name of the module.</param>
        /// <param name="activityName">Name of the activity.</param>
        /// <param name="description">The description.</param>
        /// <param name="extendedProperties">The exeteneded properties.</param>
        public ActivityContext(string moduleId, string activityName, string description = "", IDictionary<string, object> extendedProperties = null)
        {
            Guard.ArgumentNotNullOrEmpty(moduleId, "moduleName");
            Guard.ArgumentNotNullOrEmpty(activityName, "activityName");

            description = description ?? string.Empty;
            this.ActivityId = Trace.CorrelationManager.ActivityId;
            this.ModuleId = moduleId;
            this.ActivityName = activityName;
            this.Description = description ?? string.Empty;
            this.StartTime = LocalizationSettings.NeedConvertUtc()? DateTime.UtcNow : DateTime.Now;
            this.ExtendedProperties = extendedProperties ?? new Dictionary<string, object>();
        }
        #endregion        

        #region Public Static Property

        /// <summary>
        /// Gets or sets the current <see cref="ActivityContext"/>.
        /// </summary>
        /// <value>
        /// The current <see cref="ActivityContext"/>.
        /// </value>
        public static ActivityContext Current 
        {
            get { return current; }
            set { current = value; }
        }
        #endregion 
    }
}